#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project ：back 
@File    ：login_svc.py.py
@IDE     ：PyCharm 
@Author  ：七分是你
@Date    ：2024/6/28 下午7:45 
@explain : 
"""
import time

from cerberus import Validator
from fastapi import Request

from app import dao, utils
from app.constant import *
from app.service.v1.identity_token import IdentityToken
from app.service.v1.notify_rule import NotifyRule
from app.service.v1.task import Task
from app.types import appproto
from app.types.appproto import MemberInfoResponse
from app.utils import JwtManageUtil
from app.utils.str_util import StringUtil


class LoginService:
    """用户登录服务"""

    @classmethod
    def code_login(cls, mobile: str, code: str, utype: int, request: Request) -> utils.HttpResponse:
        """手机号验证码登录"""
        rules = {
            'mobile': {
                'type': 'string',
                'regex': '^1[3-9]\\d{9}$',
                'required': True
            },
            'code': {
                'type': 'string',
                'minlength': 6,
                'maxlength': 6,  # 或者直接 'length': 6（但 Cerberus 不直接支持 length）
                'required': True
            },
            'utype': {
                'type': 'integer',
                'allowed': [1, 2],
                'required': True
            }
        }
        validator = Validator(rules)
        data = {"mobile": mobile, "code": code, "utype": utype}
        if not validator.validate(data):
            errmsg = ''
            if 'code' in validator.errors:
                errmsg += '验证码是6位验证码 '
            if 'mobile' in validator.errors:
                errmsg += '手机号错误 '
            if 'utype' in validator.errors:
                errmsg += '身份类型错误'
            print(validator.errors)
            return utils.ResponseFail(errmsg, LOGIN_FORM_FAIL)
        if code != mobile:
            return utils.ResponseFail("验证码错误！", LOGIN_CODE_FAIL)
        member, points = dao.MemberQueryDao.find_member_info(**{'mobile': data['mobile']})
        is_reg = 0
        if not member:
            if StringUtil.webConfig('closereg') == 1:
                return utils.ResponseFail("网站已关闭会员注册！", REGISTER_CLOSE_FAIL)
            is_reg = 1
            if utype == 1:
                # 注册企业
                member = cls.reg_company(data, request)
            else:
                # 注册普通会员
                member = cls.reg_personal(data, request)
            if not member:
                return utils.ResponseFail("未知错误")
        elif member.status == 0:
            return utils.ResponseFail("账号已被暂停使用", MEMBER_STATUS_FAIL)

        # 通知完整度
        if data['utype'] == 2 and is_reg == 0:
            # 刷新简历信息
            print("刷新简历信息")
            notify_alias = ''
            print("刷新简历信息model('Resume')->countCompletePercent", notify_alias)
            # if ($compelte_percent <= 55) {
            # $notify_alias = 'resume_complete_too_low';
            # } elseif ($compelte_percent <= 75) {
            # $notify_alias = 'resume_complete_lower';
            # }
            if notify_alias != '':
                NotifyRule.notify(member.uid, 2, notify_alias)
        if not isinstance(member, appproto.MemberInfoResponse):
            member = appproto.MemberInfoResponse(uid=member.uid, utype=member.utype, mobile=member.mobile)
        jwtUtil = JwtManageUtil()
        token = jwtUtil.generate(member)
        expire = int(StringUtil.webConfig('token_expire'))
        if expire >= 10:
            expire = expire * 60
        else:
            # 默认7天有效期
            expire = 604800
        dao.redis_dao.set(member.uid, member.model_dump_json(), expire)
        IdentityToken.makeToken(member.uid, token)
        dao.redis_dao.set('visitor' + str(member.uid), token)
        result = {'uid': member.uid, 'token': token, 'utype': member.utype, 'expire': expire}
        return utils.ResponseSuccess(result)

    @classmethod
    def univerify_login(cls, mobile: str, utype: int, request: Request) -> utils.HttpResponse:
        """手机号验证码登录"""
        rules = {
            'mobile': {
                'type': 'string',
                'regex': '^1[3-9]\\d{9}$',
                'required': True
            },
            'utype': {
                'type': 'integer',
                'allowed': [1, 2],
                'required': True
            }
        }
        validator = Validator(rules)
        data = {"mobile": mobile, "utype": utype}
        if not validator.validate(data):
            errmsg = ''
            if 'mobile' in validator.errors:
                errmsg += '手机号错误 '
            if 'utype' in validator.errors:
                errmsg += '身份类型错误'
            print(validator.errors)
            return utils.ResponseFail(errmsg, LOGIN_FORM_FAIL)
        member, points = dao.MemberQueryDao.find_member_info(**{'mobile': data['mobile']})
        is_reg = 0
        if not member:
            if StringUtil.webConfig('closereg') == 1:
                return utils.ResponseFail("网站已关闭会员注册！", REGISTER_CLOSE_FAIL)
            is_reg = 1
            if utype == 1:
                # 注册企业
                member = cls.reg_company(data, request)
            else:
                # 注册普通会员
                member = cls.reg_personal(data, request)
            if not member:
                return utils.ResponseFail("未知错误")
        elif member.status == 0:
            return utils.ResponseFail("账号已被暂停使用", MEMBER_STATUS_FAIL)

        # 通知完整度
        if data['utype'] == 2 and is_reg == 0:
            # 刷新简历信息
            print("刷新简历信息")
            notify_alias = ''
            print("刷新简历信息model('Resume')->countCompletePercent", notify_alias)
            # if ($compelte_percent <= 55) {
            # $notify_alias = 'resume_complete_too_low';
            # } elseif ($compelte_percent <= 75) {
            # $notify_alias = 'resume_complete_lower';
            # }
            if notify_alias != '':
                NotifyRule.notify(member.uid, 2, notify_alias)
        if not isinstance(member, appproto.MemberInfoResponse):
            member = appproto.MemberInfoResponse(uid=member.uid, utype=member.utype, mobile=member.mobile)
        jwtUtil = JwtManageUtil()
        token = jwtUtil.generate(member)
        expire = int(StringUtil.webConfig('token_expire'))
        if expire >= 10:
            expire = expire * 60
        else:
            # 默认7天有效期
            expire = 604800
        dao.redis_dao.set(member.uid, member.model_dump_json(), expire)
        IdentityToken.makeToken(member.uid, token)
        dao.redis_dao.set('visitor' + str(member.uid), token)
        result = {'uid': member.uid, 'token': token, 'utype': member.utype, 'expire': expire}
        return utils.ResponseSuccess(result)

    @classmethod
    def reg_personal(cls, data, request: Request) -> MemberInfoResponse | None:
        # data = {"mobile": mobile, "code": code, "utype": utype}
        reg_prefix = StringUtil.webConfig('reg_prefix')
        platform = "App"
        password = data['password'] if 'password' in data else ''
        insert_data_member = {
            'username': reg_prefix + data['mobile'],
            'password': password,
            'mobile': data['mobile'],
            'platform': platform,
            'pwd_hash': StringUtil.generate_captcha_text(),
            'utype': 2,
            'email': '',
            'reg_time': int(time.time()),
            'reg_ip': request.client.host,
            'reg_address': StringUtil.get_client_ipaddress(request.client.host),
            'last_login_time': int(time.time()),
            'last_login_ip': request.client.host,
            'last_login_address': StringUtil.get_client_ipaddress(request.client.host),
            'status': 1,
            'avatar': '',
            'robot': 0,
        }
        # 新增到会员表
        if insert_data_member['password'] != '':
            insert_data_member['password'] = StringUtil.makeMd5Password(insert_data_member['password'],
                                                                        insert_data_member['pwd_hash'])
        else:
            insert_data_member['password'] = ''

        member = dao.MemberOperateDao.save_member(insert_data_member)
        if not member:
            return None
        print("member===", member.uid)
        Task.do_task(member.uid, 2, 'reg')
        NotifyRule.notify(member.uid, 2, 'reg',
                          {'sitename': StringUtil.webConfig('sitename'), 'mobile': StringUtil.webConfig('contact_tel')})
        return appproto.MemberInfoResponse(**{'uid': member.uid, 'utype': 2, 'mobile': data['mobile']})

    @classmethod
    def reg_company(cls, data, request: Request) -> MemberInfoResponse | None:
        reg_prefix = StringUtil.webConfig('reg_prefix')
        platform = "App"
        password = data['password'] if 'password' in data else ''
        insert_data_member = {
            'username': reg_prefix + data['mobile'],
            'password': password,
            'mobile': data['mobile'],
            'platform': platform,
            'pwd_hash': StringUtil.generate_captcha_text(),
            'utype': 1,
            'email': '',
            'reg_time': int(time.time()),
            'reg_ip': request.client.host,
            'reg_address': StringUtil.get_client_ipaddress(request.client.host),
            'last_login_time': int(time.time()),
            'last_login_ip': request.client.host,
            'last_login_address': StringUtil.get_client_ipaddress(request.client.host),
            'status': 1,
            'avatar': '',
            'robot': 0,
        }
        # 新增到会员表
        if insert_data_member['password'] != '':
            insert_data_member['password'] = StringUtil.makeMd5Password(insert_data_member['password'],
                                                                        insert_data_member['pwd_hash'])
        else:
            insert_data_member['password'] = ''
        member = dao.MemberOperateDao.save_member(insert_data_member)
        if not member:
            return None
        # 其他注册到企业相关逻辑 增加到企业列表，企业名称等信息 后面再加
        # todo
        Task.do_task(member.uid, 1, 'reg')
        NotifyRule.notify(member.uid, 1, 'reg',
                          {'sitename': StringUtil.webConfig('sitename'), 'mobile': StringUtil.webConfig('contact_tel')})
        return appproto.MemberInfoResponse(**{'uid': member.uid, 'utype': 1, 'mobile': data['mobile']})
